home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / setVGAreg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-21  |  10.8 KB  |  356 lines

  1. /*  SVGATextMode -- An SVGA textmode manipulation/enhancement tool
  2.  *
  3.  *  Copyright (C) 1995,1996  Koen Gadeyne
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20.  
  21. /***
  22.  *** get/set VGAreg, a simple VGA register hacking program
  23.  ***
  24.  *** WARNING: since different SVGA cards use different extra address ranges in any 
  25.  *** of the register sets, no checking is done to make sure you don't attempt to change
  26.  *** a non-existing register!
  27.  ***
  28.  *** This is just a hacking tool! Use at your own risk. It was NOT intended to be 
  29.  *** idiot proof! If you don't understand all this, then don't bother trying to use it.
  30.  ***
  31.  ***/
  32.  
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36.  
  37. #define CHIPSETREC 1
  38. #include "chipset.h"
  39. #include "misc.h"
  40. #include "vga_prg.h"
  41. #include "file_ops.h"
  42. #include "string_ops.h"
  43. #include "messages.h"
  44. #include "cfg_structs.h"
  45.  
  46. char *CommandName;
  47. char *ConfigFile=CONFIGFILE;
  48.  
  49. extern int yyparse(void);
  50. extern FILE *yyin;
  51. #define param_file yyin
  52.  
  53. bool debug_messages=FALSE;
  54.  
  55. /* this adds all the global variables that hold the data from the config file. */
  56. #include "cfg_data.h"
  57.  
  58.  
  59. /*
  60.  * Supported Register Sets
  61.  */
  62.  
  63. #define REGSET_CRTC        0
  64. #define REGSET_SEQ         1
  65. #define REGSET_ATRCTL      2
  66. #define REGSET_GRCTL       3
  67. #define REGSET_MISC        4
  68. #define REGSET_DAC_STATUS  5
  69. #define REGSET_DAC_MASK    6
  70. #define REGSET_DAC         7
  71.  
  72. #define RT_INDEX         1
  73. #define RT_MEMMAP        2
  74.  
  75. t_str_token RegsetRec[] = {
  76.   { "CRTC",       REGSET_CRTC       },
  77.   { "SEQ",        REGSET_SEQ        },
  78.   { "ATRCTL",     REGSET_ATRCTL     },
  79.   { "GRCTL",      REGSET_GRCTL      },
  80.   { "MISC",       REGSET_MISC       },
  81.   { "DAC_STATUS", REGSET_DAC_STATUS },
  82.   { "DAC_MASK",   REGSET_DAC_MASK   },
  83.   { "DAC",        REGSET_DAC        },
  84.   { "",           ENDREC            }
  85. };
  86.  
  87. typedef const struct {
  88.     int regset;
  89.     int type;
  90. } t_regset_type ;
  91.  
  92. t_regset_type RegsetType[] = {
  93.   { REGSET_CRTC       , RT_INDEX  },
  94.   { REGSET_SEQ        , RT_INDEX  },
  95.   { REGSET_ATRCTL     , RT_INDEX  },
  96.   { REGSET_GRCTL      , RT_INDEX  },
  97.   { REGSET_MISC       , RT_MEMMAP },
  98.   { REGSET_DAC_STATUS , RT_MEMMAP },
  99.   { REGSET_DAC_MASK   , RT_MEMMAP },
  100.   { REGSET_DAC        , RT_INDEX  },
  101.   { -1                , ENDREC    }
  102. };
  103.          
  104. void outb_VGA_mem(int register_set, int data)
  105. {
  106.    switch(register_set)
  107.   {
  108.     case REGSET_MISC  : outb(data, VGA_MISC_W); break;
  109.     case REGSET_DAC_STATUS : PWARNING(("DAC_STATUS is read-only.\n")); break;
  110.     case REGSET_DAC_MASK : outb(data, DAC_MASK); break;
  111.     default: PERROR(("outb_VGA_indexed: unknown register set %d\n",register_set));
  112.   }
  113. }
  114.  
  115. int inb_VGA_mem(int register_set)
  116. {
  117.    switch(register_set)
  118.   {
  119.     case REGSET_MISC  : return(inb(VGA_MISC_R)); break;
  120.     case REGSET_DAC_STATUS  : return(inb(DAC_STATUS)); break;
  121.     case REGSET_DAC_MASK : return(inb(DAC_MASK)); break;
  122.     default: PERROR(("inb_VGA_indexed: unknown register set %d\n",register_set));
  123.   }
  124. }
  125.  
  126. void outb_VGA_indexed(int register_set, int reg_index, int data)
  127. {
  128.    switch(register_set)
  129.   {
  130.     case REGSET_CRTC  : Outb_CRTC(reg_index,data); break;
  131.     case REGSET_SEQ   : Outb_SEQ(reg_index,data); break;
  132.     case REGSET_ATRCTL: Outb_ATR_CTL(reg_index,data); break;
  133.     case REGSET_GRCTL : Outb_GR_CTL(reg_index,data); break;
  134.     case REGSET_DAC   : OutRGB_DAC(reg_index,data); break; /* 24 bit! */
  135.     default: PERROR(("outb_VGA_indexed: unknown register set %d\n",register_set));
  136.   }
  137. }
  138.  
  139. int inb_VGA_indexed(int register_set, int reg_index)
  140. {
  141.    switch(register_set)
  142.   {
  143.     case REGSET_CRTC  : return(Inb_CRTC(reg_index)); break;
  144.     case REGSET_SEQ   : return(Inb_SEQ(reg_index)); break;
  145.     case REGSET_ATRCTL: return(inb_ATR_CTL(reg_index)); break;
  146.     case REGSET_GRCTL : return(Inb_GR_CTL(reg_index)); break;
  147.     case REGSET_DAC   : return(InRGB_DAC(reg_index)); break; /* 24 bit! */
  148.     default: PERROR(("inb_VGA_indexed: unknown register set %d\n",register_set));
  149.   }
  150. }
  151.  
  152. char* int_to_bin(int num, int bits)
  153. {
  154.   static char binstr[sizeof(long int)+1];
  155.   int i;
  156.   
  157.   for (i=0; i<bits; i++) binstr[i] = 0x30; /* char '0' */
  158.   binstr[bits] = 0x00;
  159.   
  160.   for (i=0; i<bits; i++) binstr[bits-1-i] += ((num >> i) & 0x00000001);
  161.   PDEBUG(("binstr = '%s'\n", binstr));
  162.   return(binstr);
  163. }
  164.  
  165. /* this is nearly identical to the one in cfglex.l. Consider merging them */
  166.  
  167. int local_find_token(t_str_token *rec, char *ch_str)
  168. {
  169.   int i = 0;
  170.   while (rec[i].name!=CS_NONE)
  171.   {
  172.     if (!strcasecmp(rec[i].name_str,ch_str))
  173.     {
  174.       if (i != rec[i].name)
  175.       {
  176.         PERROR(("Internal error in setVGAreg.c: rec[].name/offset mismatch: i=%d, rec[i].name=%d\n",\
  177.                  i, rec[i].name));
  178.       }
  179.       return i;
  180.     }
  181.     i++;
  182.   }
  183.   PERROR(("Unknown Register set `%s' on command line\n", ch_str));
  184.   return CS_NONE;
  185. }
  186.  
  187.  
  188. void usage(int setreg)
  189. {
  190.      int i=0;
  191.      
  192.      PMESSAGE(("version %s. (c) 1995,1996 Koen Gadeyne.\n"\
  193.      "  Usage: %s [options] VGA_register_set [register_index] %s\n\n"\
  194.      "  Options: -h  print usage information\n"\
  195.      "           -n  Don't program VGA hardware\n"\
  196.      "           -d  print debugging information\n"\
  197.      "           -u  unlock chipset-specific registers\n"\
  198.      "               (needs SVGAtextMode config file)\n"\
  199.      "           -p  produce 'pipeable' decimal output (= just numbers, no text)\n"\
  200.      "           -x  produce 'pipeable' hex output\n"\
  201.      "           -t <ConfigFile>\n"\
  202.      "                 Use <ConfigFile> instead of the default (%s)\n"\
  203.      "                 (only useful for '-u' option)\n"\
  204.      "  register_index: An index in the specified VGA_register_set,\n"\
  205.      "                  In decimal (e.g. '24'), hex ('0x18') or octal ('030').\n"\
  206.      "                  Only needed when it is an indexed (indirect) VGA register.\n"\
  207.      "%s",\
  208.      VERSION,\
  209.      CommandName,\
  210.      (setreg) ? "data" : "",\
  211.      CONFIGFILE,\
  212.      (setreg) ? "  data: the data to program into the specified register (dec|hex|oct).\n" : ""));
  213.      
  214.      printf("  VGA_register_set: any of the following:\n ");
  215.      i=0;
  216.      while (RegsetRec[i].name != ENDREC)
  217.      {
  218.        printf(" `%s'", RegsetRec[i].name_str);
  219.        i++;
  220.      }
  221.      putchar('\n');
  222. }
  223.  
  224.  
  225. /***********************************************************************************************************/
  226.  
  227. int main (int argc, char* argv[])
  228. {
  229.   bool program_hardware=TRUE;
  230.   bool unlock_chipset=FALSE;
  231.   bool pipehex=FALSE;
  232.   bool pipe=FALSE;
  233.   int regset = -1;
  234.   int c;
  235.   int tmpbyte=0;
  236.   int regnum=0;
  237.   bool setreg = FALSE; /* if TRUE: "getVGAreg" function, if FALSE, "setVGAreg" function */
  238.   char* commandfilename;
  239.   int data=0;
  240.   
  241.  /*
  242.   * See what action is required: read or write VGA register
  243.   */
  244.     
  245.   CommandName = argv[0];
  246.   commandfilename = strrchr(CommandName, '/');
  247.   if (commandfilename) commandfilename++;
  248.   else commandfilename = CommandName;
  249.   setreg = (!strncasecmp(commandfilename,"set",3));
  250.   
  251.  
  252.  /*
  253.   * command-line argument parsing
  254.   */
  255.  
  256.   while ((c = getopt (argc, argv, "ndhupxt:")) != EOF)
  257.     switch (c)
  258.     {
  259.       case 'n': program_hardware=FALSE;
  260.                 break;
  261.       case 'd': debug_messages=TRUE;
  262.                 break;
  263.       case 'h': usage(setreg);
  264.                 exit(0);
  265.                 break;
  266.       case 'u': unlock_chipset = TRUE;
  267.                 break;
  268.       case 'p': pipe = TRUE;
  269.                 break;
  270.       case 'x': pipehex = TRUE;
  271.                 break;
  272.       case 't': ConfigFile=safe_strdup(optarg);
  273.                 break;
  274.       case '?': usage(setreg);
  275.                 PERROR(("Bad option '-%c'\n",(char)optopt));
  276.                 exit(-1);
  277.                 break;
  278.       default: PERROR(("getopt returned unknown token '%c'.\n",c));
  279.     }
  280.     
  281.   PVERSION;
  282.  
  283.   PDEBUG(("'%cetVGAreg' function selected through command name '%s'\n", (setreg) ? 's' : 'g', commandfilename));
  284.  
  285.   /* get register set from commandline */
  286.   if (argc<optind+1) PERROR(("Missing register set on commandline\n"));
  287.  
  288.   regset = local_find_token(RegsetRec, argv[optind]);
  289.  
  290.   /* get register index, if an indexed register set was specified */
  291.   if (RegsetType[regset].type == RT_INDEX)
  292.   {
  293.     optind++;
  294.     if (argc<optind+1) PERROR(("Missing register index for '%s' register set\n", RegsetRec[regset].name));
  295.     regnum = getint(argv[optind], "register number", 0, 255);
  296.     PDEBUG(("register index = %d (0x%x).\n", regnum, regnum));
  297.   }
  298.  
  299.   /* get register data, if 'set'VGAreg command */
  300.   if (setreg)
  301.   {
  302.     optind++;
  303.     if (argc<optind+1) PERROR(("Missing register data\n"));
  304.     data = getint(argv[optind], "register data", 0, regset==REGSET_DAC ? (256 << 16) -1 : 255);
  305.     PDEBUG(("register data to write = %d (0x%x).\n", data, data));
  306.   }
  307.   optind++;  
  308.   if (argc>optind) PWARNING(("Extra parameters (starting with '%s') ignored\n", argv[optind])); 
  309.   
  310.  
  311.  /*
  312.   * open parameter file if needed for unlocking chipset, use only chipset definition (until now)
  313.   * This is a bit of an overkill, to parse the whole file just to get the chipset from it, but what the heck.
  314.   */
  315.   chipset = CS_VGA; /* if not defined: chipset = standard VGA */
  316.   if (unlock_chipset)
  317.   {
  318.     param_file = open_param_file(ConfigFile);
  319.     PDEBUG(("Parsing Config file...\n"));
  320.     while (!feof(yyin)) { yyparse(); }
  321.     fclose(param_file);
  322.     if (chipset<0) PERROR(("No chipset defined in config file\n"));
  323.   }  
  324.  
  325. /*
  326.  * start doing something useful
  327.  */
  328.  
  329.  if (program_hardware)
  330.   {
  331.      get_VGA_io_perm(chipset);
  332.      if (unlock_chipset) unlock(chipset); 
  333.      if (RegsetType[regset].type==RT_INDEX)
  334.      {
  335.        if (setreg) outb_VGA_indexed(regset, regnum, data);
  336.        tmpbyte = inb_VGA_indexed(regset, regnum);
  337.        if (pipe) printf("%d\n",tmpbyte);
  338.        else if (pipehex) printf("0x%02x\n",tmpbyte);
  339.        else printf("VGA '%s' register, index %d (=0x%x) contains %d (=0x%02x =b%s)\n",
  340.                     RegsetRec[regset].name_str, regnum, regnum, tmpbyte, tmpbyte,
  341.                     regset==REGSET_DAC ? int_to_bin(tmpbyte,24): int_to_bin(tmpbyte,8));
  342.      }
  343.      else
  344.      {
  345.        if (setreg) outb_VGA_mem(regset, data);
  346.        tmpbyte = inb_VGA_mem(regset);
  347.        if (pipe) printf("%d\n",tmpbyte);
  348.        else if (pipehex) printf("0x%02x\n",tmpbyte);
  349.        else printf("VGA '%s' register contains %d (=0x%02x =b%s)\n",
  350.                     RegsetRec[regset].name_str, tmpbyte, tmpbyte,
  351.                     regset==REGSET_DAC ? int_to_bin(tmpbyte,24): int_to_bin(tmpbyte,8));
  352.      }
  353.   }
  354.   return(0);
  355. }
  356.